package org.onion.pattern.event.springboot.rocketmq.publish;


import com.github.f4b6a3.uuid.UuidCreator;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.onion.pattern.event.domain.DomainEvent;
import org.onion.pattern.event.domain.Event;
import org.onion.pattern.event.io.EventSerializer;
import org.onion.pattern.event.io.codec.JacksonEventCodec;
import org.onion.pattern.event.outbox.OutboxEventConverter;
import org.onion.pattern.event.outbox.annotation.Outbox;
import org.onion.pattern.event.outbox.data.OutboxEventStatus;
import org.onion.pattern.event.outbox.data.OutboxEventInfo;
import org.onion.pattern.event.spring.io.EventCodecs;
import org.onion.pattern.event.springboot.rocketmq.annotation.RocketMQEvent;
import org.onion.pattern.event.springboot.rocketmq.config.RocketMQ;
import org.onion.pattern.event.springboot.rocketmq.topic.RocketMQTagUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Objects;


@Component
public class RocketMQOutboxEventConverter implements OutboxEventConverter {

    @Autowired
    private EventCodecs eventCodecs;

    @Override
    public boolean support(Object event) {
        RocketMQEvent rocketMQEvent = AnnotationUtils.findAnnotation(event.getClass(), RocketMQEvent.class);
        return rocketMQEvent != null;
    }

    @Override
    public OutboxEventInfo convert(Object msg) {

        OutboxEventInfo eventInfo = new OutboxEventInfo();
        eventInfo.setOutBoxEventStatus(OutboxEventStatus.CREATED);
        eventInfo.setVer(1L);
        eventInfo.setEventKey(UuidCreator.getTimeOrderedEpoch().toString());
        eventInfo.setEventTime(System.currentTimeMillis());
        eventInfo.setSerializer(JacksonEventCodec.TYPE);
        eventInfo.setTopic(msg.getClass().getSimpleName());
//        eventInfo.setSubTopic(StringUtils.replace(msg.getClass().getName(), ".", "-"));
        eventInfo.setSubTopic("");
        eventInfo.setProps(null);
        eventInfo.setChannel(RocketMQ.CHANNEL_NAME);
        eventInfo.setDomainType(msg.getClass().getName());
        eventInfo.setDomainId("none");
        eventInfo.setGroup(OutboxEventInfo.NONE_GROUP);

        if (msg instanceof Event) {
            Event event = (Event) Objects.requireNonNull(msg);
            eventInfo.setEventKey(event.eventKey());
            if(event.eventTime()!=null){
                LocalDateTime localDateTime = event.eventTime();
                Instant eventTimeInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
                eventInfo.setEventTime(ObjectUtils.defaultIfNull(eventTimeInstant.toEpochMilli(), eventInfo.getEventTime()));
            }
        }

        if (msg instanceof DomainEvent) {
            DomainEvent domainEvent = (DomainEvent) msg;
            eventInfo.setDomainId(domainEvent.domainId().toString());
        }

        eventInfo.setSubTopic(RocketMQTagUtils.getTag(msg.getClass()));

        RocketMQEvent rocketMQEvent = AnnotationUtils.findAnnotation(msg.getClass(), RocketMQEvent.class);
        Assert.notNull(rocketMQEvent,"");
        eventInfo.setTopic(StringUtils.defaultIfBlank(rocketMQEvent.value(), eventInfo.getTopic()));
        eventInfo.setSerializer(StringUtils.defaultIfBlank(rocketMQEvent.serializer(),eventInfo.getSerializer()));


        Outbox outbox = AnnotationUtils.findAnnotation(msg.getClass(), Outbox.class);
        if (outbox != null) {
            eventInfo.setGroup(StringUtils.defaultIfBlank(outbox.value(), eventInfo.getGroup()));
            eventInfo.setSerializer(StringUtils.defaultIfBlank(outbox.serializer(), eventInfo.getSerializer()));
        }

        //序列化

        EventSerializer eventSerializer = this.eventCodecs.serialize(eventInfo.getSerializer());

        eventInfo.setPayload(eventSerializer.serialize(msg));

        return eventInfo;
    }

    @Override
    public boolean support(OutboxEventInfo event) {
        return false;
    }

    @Override
    public Object convert(OutboxEventInfo eventInfo) {
        //TODO  2025-08-18 23:31  何挺强
        return null;
    }
}
